// Copyright 2011, Vanya Davidenko.
// Кодировка файла: UTF-8. 
package info.iu9.red;




final class NfaState implements Cloneable {
  public NfaState clone() {
    try {
      final NfaState result = (NfaState)super.clone();
      result.state_id_ = state_id_;
      result.processed_ = processed_.clone();
      result.submatches_ = submatches_.clone();
      return result;
    } catch(CloneNotSupportedException e) {
      assert false;
      return null;
    }
  }

  NfaState(final int state_id,
           final int max_num_states,
           final int num_submatches) {
    state_id_ = state_id;
    processed_ = new StateIdSetList(max_num_states);
    submatches_ = new int[num_submatches * 2];
    for ( int i = 0 ; i != submatches_.length ; i++ ) {
      submatches_[i] = NO_VALUE;
    }
  }

  int num_submatches() {
    return submatches_.length / 2;
  }
  Submatch makeSubmatch(final String s, final int num) {
    if ( submatches_[num * 2] == NO_VALUE ) {
      assert submatches_[num * 2 + 1] == NO_VALUE;
      return new Submatch(s);
    }

    // Пустая строка.
    if ( submatches_[num * 2] - 1 == submatches_[num * 2 + 1] ) {
      return new Submatch(s);
    }

    return new Submatch(s, submatches_[num * 2], submatches_[num * 2 + 1]);
  }

  void setSubmatchBegin(final int num, final int str_first_index) {
    assert num >= 0;
    submatches_[num * 2] = str_first_index;
  }
  void setSubmatchEnd(final int num, final int str_last_index) {
    assert num >= 0;
    assert submatches_[num * 2] != NO_VALUE;
    submatches_[num * 2 + 1] = str_last_index;
  }

  int state_id() {
    return state_id_;
  }
  boolean set_state_id(final int state_id) {
    if ( isProcessed(state_id) ) { return false; }
    state_id_ = state_id;
    processed_.pushNew(state_id);
    return true;
  }

  boolean isProcessed(final int state_id) {
    return processed_.contains(state_id);
  }
  void clearProcessed() {
    processed_.clear();
  }

  private int state_id_;
  private /*final*/ StateIdSetList processed_;
  private /*final*/ int[] submatches_;

  private static final int NO_VALUE = -5;
}

